package com.stone.base.dao;

import java.math.BigInteger;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.stone.base.entity.Page;
import com.stone.common.util.StringFormatUtil;
import java.io.Serializable;

public class BaseDao implements IBaseDao {
	@Autowired
	protected HibernateTemplate hibernateTemplate;
	
	public Session getSession() {
		return hibernateTemplate.getSessionFactory().getCurrentSession();
	}
	
	/**
	 * 查询分页数据
	 * @param hql			查询HQL语句
	 * @param pageNumber	当前页
	 * @param params		参数
	 * @return
	 */
	public Page queryPage(final String hql, final Integer pageNumber, final Object... params) {
		Page page = new Page();
		final Integer pageSize = page.getPageSize();
		//总记录数
		Integer totalCount = totalCount(hql, params);
		page.setPageSize(page.getPageSize());
		//总记录数
		page.setTotalCount(totalCount);
		//当前页
		page.setPageCurrent(pageNumber);
		//获取数据集合
		List list = this.hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query q = session.createQuery(StringFormatUtil.format(hql, params)).setFirstResult(
						(pageNumber - 1) * pageSize).setMaxResults(pageSize);
				return q.list();
			}
		});
		//把集合放入到page对象中
		page.setResultList(list);
		page.setPageCount(totalCount % pageSize == 0 ? totalCount / pageSize
				: totalCount / pageSize + 1);
		return page;
	}

	/**
	 * 计算总记录数
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Integer totalCount(String hql, final Object[] objects) {
		Long totalCount = 0L;
		String tempHql = hql.toLowerCase();
		int from = tempHql.indexOf("from");
		int index = tempHql.indexOf("order by");
		//order by存在
		if (index != -1) {
			hql = "select count(*) " + hql.substring(from, index);
		} else {
			//order by不存在
			hql = "select count(*) " + hql.substring(from);
		}
		final String queryString = hql;
		totalCount = (Long) hibernateTemplate.execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query q = session.createQuery(StringFormatUtil.format(queryString, objects));
				return q.uniqueResult();
			}
		});
		return totalCount.intValue();
	}
	
	/**
	 * SQL语句查询分页数据
	 * @param sql			查询SQL语句
	 * @param pageNumber	当前页
	 * @param params		参数
	 * @return
	 */
	public Page queryPageBySql(final String sql, final Integer pageNumber, final Object... params) {
		Page page = new Page();
		final Integer pageSize = page.getPageSize();
		//总记录数
		Integer totalCount = totalCountBySql(sql, params);
		page.setPageSize(page.getPageSize());
		//总记录数
		page.setTotalCount(totalCount);
		//当前页
		page.setPageCurrent(pageNumber);
		//获取数据集合
		List list = this.hibernateTemplate.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query q = session.createSQLQuery(StringFormatUtil.format(sql, params)).setFirstResult(
						(pageNumber - 1) * pageSize).setMaxResults(pageSize);
				return q.list();
			}
		});
		//把集合放入到page对象中
		page.setResultList(list);
		page.setPageCount(totalCount % pageSize == 0 ? totalCount / pageSize
				: totalCount / pageSize + 1);
		return page;
	}

	/**
	 * 计算总记录数
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Integer totalCountBySql(String hql, final Object[] objects) {
		BigInteger totalCount;
		String tempHql = hql.toLowerCase();
		int from = tempHql.indexOf("from");
		int index = tempHql.indexOf("order by");
		//order by存在
		if (index != -1) {
			hql = "select count(*) " + hql.substring(from, index);
		} else {
			//order by不存在
			hql = "select count(*) " + hql.substring(from);
		}
		final String queryString = hql;
		totalCount = (BigInteger) hibernateTemplate.execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query q = session.createSQLQuery(StringFormatUtil.format(queryString, objects));
				return q.uniqueResult();
			}
		});
		return totalCount.intValue();
	}

    @Override
    public <T> T get(Class<T> cls, Serializable pk) {
        if(pk == null)
            return null;
        return this.hibernateTemplate.get(cls, pk);
    }

    @Override
    public <T> T remove(T entity) {
        if(entity == null)
            return null;
        this.hibernateTemplate.delete(entity);
        return entity;
    }

    @Override
    public <T> T update(T entity) {
        if(entity == null)
            return null;
        this.hibernateTemplate.saveOrUpdate(entity);
        return entity;
    }
}
